#if !defined(MQTTSERVICE_H)
#define MQTTSERVICE_H

#if defined(__cplusplus)
 extern "C" {
#endif
#include "MQTTClient.h"
/**
 * This function creates an MQTT client ready for connection to the
 * specified server.
 * @param client A pointer to an ::MQTTClient handle. The handle is
 * populated with a valid client reference following a successful return from
 * this function.
 * @param addr A null-terminated string specifying the server to
 * which the client will connect. Its format should be "protocol + broker hostname/ip + port"
 * protocal must be:
 * @em tcp:// or @em mqtt:// - Insecure TCP
 * @em ssl:// or @em mqtts:// - Encrypted SSL/TLS
 * @em ws:// - Insecure websockets
 * @em wss:// - Secure web sockets
 * "tcp://localhost:1883"
 * 
 * @param clientId The client identifier passed to the server when the
 * client connects to it. It is a null-terminated UTF-8 encoded string.
 * 
 * @return 0 - success, other - error
 * error codes are defined in MQTTClient.h, starts at line 138
 */
int MqttClientInit(MQTTClient* client,char* addr, char* client_id);   
/**
  * This function attempts to connect a previously-created client to an MQTT server using the specified options.
  * If you want to enable asynchronous message and status notifications, you must call
  * MQTTClient_setCallbacks() prior to MQTTClient_connect().
  * @param client A valid client handle from a successful call to
  * MqttClientInit().
  * @param conn_opts A pointer to a valid MQTTClient_connectOptions
  * structure.
  * 
  * @return 0 - success, other - error
  * error codes > 0  are returned by MQTT protocol:
  * 1: Connection refused: Unacceptable protocol version
  * 2: Connection refused: Identifier rejected
  * 3: Connection refused: Server unavailable
  * 4: Connection refused: Bad user name or password
  * 5: Connection refused: Not authorized
  * 6-255: Reserved for future use
  * 
  * other error codes are defined in MQTTClient.h, starts at line 138
  */
int MqttConnect(MQTTClient* client,MQTTClient_connectOptions* conn_opts);
/**
 * Currutly, This function is completely the same as MqttConnect()
 * It may be restruct in the future.
 */
int MqttConnectSSL(MQTTClient* client,MQTTClient_connectOptions* conn_opts);
/**
  * This function attempts to publish a message to a given topic 
  * @param client A valid client handle from a successful call to
  * MQTTClient_create().
  * @param pubmsg A pointer to a valid MQTTClient_message structure containing
  * the payload and attributes of the message to be published.
  * @param topic The topic associated with this message.
  * @param timeout MAX wait time in milliseconds
  * 
  *  @return 0 - success, other - error
  * error codes are defined in MQTTClient.h, starts at line 138
  */
int MqttPublishMsg(MQTTClient* client, MQTTClient_message* pubmsg, char* topic, long unsigned int timeout);
/**
  * This function attempts to disconnect the client from the MQTT
  * server. In order to allow the client time to complete handling of messages
  * that are in-flight when this function is called, a timeout period is
  * specified. When the timeout period has expired, the client disconnects even
  * if there are still outstanding message acknowledgements.
  *
  * Resource allocated to the client will be free after disconnect.
  * 
  * @param client A valid client handle from a successful call to
  * MQTTClient_create().
  * @param timeout The client delays disconnection for up to this time (in
  * milliseconds) in order to allow in-flight message transfers to complete.
  * @return ::MQTTCLIENT_SUCCESS if the client successfully disconnects from
  * the server. An error code is returned if the client was unable to disconnect
  * from the server
  */
int MqttDisconnect(MQTTClient* client, int timeout);   
/**
 * This function is only for test
 */
int mqtt_publish_test();
#if 0
/* -----------A publish test example---------- */
void mqtt_publish_test(){
    MQTTClient client;
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    
    int result = 0;
    
    //set Broker address and Client ID
    result = MqttClientInit(&client, "tcp://192.168.9.73:1883", "Client_test");    
    if(result != 0){
	return;
    }
    
    //configure connect options
    conn_opts.keepAliveInterval = 60;	//keep alive interval in seconds, default value is 60
    conn_opts.cleansession = 1;		//cleansession, default value is 1
    conn_opts.username = "Invengo";	//username
    conn_opts.password = "2333";	//password
    
    conn_opts.ssl = NULL;	//set to NULL if we are not connecting a SSL/TLS broker
    
    /* if we are connecting to a SSL/TLS broker, configure ssl options and attach it to connect options
    
    MQTTClient_SSLOptions ssl_opts= MQTTClient_SSLOptions_initializer;
    ssl_opts.trustStore = "ca.crt";		//path to tursted certificate file
    ssl_opts.privateKey = "client.key";		//path to client's private key
    ssl_opts.keyStore = "client.crt";		//path to client's certificate file
    ssl_opts.privateKeyPassword = "1234";	//private key password
    ssl_opts.enableServerCertAuth = 1;		//whether to verify the server certificate
    ssl_opts.sslVersion= MQTT_SSL_VERSION_TLS_1_2;	//The SSL/TLS version to use
    //attach ssl options to connect options
    conn_opts.ssl=&ssl_opts;  
    */
    
    /*will message will be published once the client disconnect form borker
    MQTTClient_willOptions will = MQTTClient_willOptions_initializer;
    will.topicName = "test/topic";
    will.message = "Client_test disconnect";
    //attach will options to connect options
    conn_opts.will = &will;
    */
    
    //connect to broker
    result = MqttConnect(&client, &conn_opts);
    if(result != 0){
	return;
    }
    
    //configure a message
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    
    pubmsg.payload = "Hello MQTT! \n";		//context of message
    pubmsg.payloadlen = 13;			//length in bytes
    pubmsg.qos = 0;				//quality of service, 0 or 1 or 2
    pubmsg.retained = 0;		//retain this message or not
    
    //publish message on topic "test/topic", with a 3000ms timeout
    result = MqttPublishMsg(&client, &pubmsg, "test/topic", 3000);
    
    //disconnect from broker
    result = MqttDisconnect(&client, 10000);
           
}
#endif
   
#if defined(__cplusplus)
     }
#endif

#endif